/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Copyright 2002-2003 by Mark Wolgemuth, All rights reserved.             */
/* Copyright 2002-2003 by Employease, Inc.  All rights reserved.           */
/*                                                                         */
/* Redistribution and use in source and binary forms, with or without      */
/* modification, are permitted provided that the following conditions      */
/* are met:                                                                */
/*                                                                         */
/*    1. Redistributions of source code must retain the above copyright    */
/* notice, this list of conditions and the following disclaimer.           */
/*    2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the     */
/* documentation and/or other materials provided with the distribution.    */
/*                                                                         */
/* THIS SOFTWARE IS PROVIDED BY THE MOD_ATHENA PROJECT ``AS IS'' AND ANY   */
/* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       */
/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      */
/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR        */
/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   */
/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,     */
/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR      */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT            */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


#include "ath_util.h"
#include "apr_lib.h"

/* private util */
static char *substring_conf(apr_pool_t *p, const char *start, int len,
                            char quote);
/* end private */

int 
ath_skip_ws(char *str, int limit)
{
    int i = 0;
    while ((str != NULL)
	   && (i < limit)
	   && ((*(str + i) == ' ')
	       || (*(str + i) == '\t')
	       )
	   )
      {
	  i++;
      }
    if ((str == NULL) || (i == limit))
	return 0;
    return i;
}

char * 
ath_getline(apr_pool_t *pool, apr_file_t *file, int limit)
{
    char *str = NULL;
    char c;
    int i = 0;
    apr_status_t rv = APR_SUCCESS;
    ASSERT(file);

    str = (char *) apr_pcalloc(pool, sizeof(char[limit]));
    *str = (int) NULL;
    while ((rv != APR_EOF)
	   && (i < limit))
      {
	  rv = apr_file_getc(&c,file);

	  if (rv != APR_EOF)
	    {
		*(str + i) = c;
		if (c != '\n')
		    i++;
		else
		  {
		      *(str + i + 1) = (int)NULL;
		      i = limit;
		  }
	    }
      }
    if (*str)
	return str;
    return NULL;
}

char * 
ath_chomp(char *str)
{
    str = ath_chompn(str, -1);
    return str;
}

char * 
ath_chompn(char *str, int limit)
{
    int i;
    for (i = 0;
	 (((i < limit) || (limit < 0)) 
	  && (str + i)
	  && (*(str + i) != (int)NULL));
	 i++);
    if ((str) && (i < limit))
      {
	  str += i;
	  if ((*(str - 1))
	      && (*(str - 1) == '\n'))
	      *(str - 1) = (int)NULL;
	  if ((*(str - 2))
	      && (*(str - 2) == '\r'))
	      *(str - 2) = (int)NULL;
      }
    else
	return NULL;
    return str;
}

char * 
ath_chomp_ws(char *str)
{
    while (*str != (int)NULL)
	str++;
    for (str--; ((*(str)) && (isspace(*(str)))); str--)
	*(str) = (int)NULL;
    return str;
}

char * 
ath_trim_comment(char *str)
{
    while ((*str != (int)NULL)
	   && (*str != '#'))
	str++;
    if (*str == '#')
	*str = (int)NULL;
    return str;
}


int 
ath_flag_is_on(const char *str_test)
{
    if ((str_test != NULL) 
	&& ((!strncmp(str_test, "1", 1))
	    || (!strncasecmp(str_test, "on", 2)) 
	    || (!strncasecmp(str_test, "true", 4)) 
	    || (!strncasecmp(str_test, "yes", 3)))
	)
	return ATHD_ON;
    return ATHD_OFF;
}

int 
ath_streq(const char *str1, const char *str2)
{
    if (str1 && str2)
      {
	  while ((*str2 != (int)NULL)
		 && (*str1 != (int)NULL) 
		 && (*str1 == *str2))
	    { 
		str1++;
		str2++;
	    }
	  if (!((u_char) *str1 - (u_char) *str2))
	      return 1;
      }
    return 0;
}

char *
ath_list_str_join(apr_pool_t *pool, const char *sep, ath_list *list)
{
    ath_node *ctx;
    char *str = "";
    int i = 0;
    if (!sep)
	sep = "";

    ath_list_rewind_r(list, &ctx);
    while (ath_list_hasnext_r(list, &ctx))
      {
	  char *elstr;
	  elstr = ath_list_getnext_r(list, &ctx);
	  str = apr_pstrcat(pool, str, (i > 0) ? sep : str, elstr, NULL);
      }
    return str;
}

int
ath_str_is_error(const char *str)
{
    if (str)
	if (strlen(str) > 3)
	    if (!strncasecmp(str, "err", 3))
		return 1;
    return 0;
}

int
ath_str_is_warn(const char *str)
{
    if (str)
	if (strlen(str) > 4)
	    if (!strncasecmp(str, "warn", 4))
		return 1;
    return 0;
}

void
ath_str_to_apr_time(char *interval, apr_time_t *time)
{
    char *pos;
    /* 1 sec base time */
    ASSERT(*time);
    ASSERT(interval);
    (*time) = (apr_time_t) (1000 * 1000);
    pos = interval;
    while ((*pos) && (isdigit(*pos)))
	pos++;
    if (*pos)
      {
	  switch (*pos)
	    {
	    case 's':
	    case 'S':
		break;
	    case 'm':
	    case 'M':
		(*time) *= 60;
		break;
	    case 'h':
	    case 'H':
		(*time) *= (60 * 60);
		break;
	    }
	  (*pos) = (int)NULL; /* null term digit section */
      }
    (*time) *= (apr_time_t) (strtoll(interval, NULL, 10));
}

int
ath_str_to_unix_sig(const char *str)
{
    ASSERT(str);
    int sig = -1;
    if (!strcasecmp(str, "kill"))
	sig = SIGKILL;
    else if ((!strcasecmp(str, "abort")) 
	     || (!strcasecmp(str, "dump"))
	     || (!strcasecmp(str, "assert")))
	sig = SIGABRT;
    else if ((!strcasecmp(str, "stop")) 
	     || (!strcasecmp(str, "shutdown"))
	     || (!strcasecmp(str, "term")))
	sig = SIGTERM;
    else if ((!strcasecmp(str, "reset")) 
	     || (!strcasecmp(str, "restart"))
	     || (!strcasecmp(str, "cleanup"))
	     || (!strcasecmp(str, "hup")))
	sig = SIGHUP;
    else if ((!strcasecmp(str, "full-restart")) 
	     || (!strcasecmp(str, "int")))
	sig = SIGINT;
    else if ((!strcasecmp(str, "mark")) 
	     || (!strcasecmp(str, "logmark")))
	sig = SIGUSR1;
    else if ((!strcasecmp(str, "check")) 
	     || (!strcasecmp(str, "pulse")))
	sig = SIGUSR2;
    else if ((!strcasecmp(str, "start")))
	sig = ATHD_SIGSTRT;
    return sig;
}

/* line for line copy of ap_getword_conf, httpd-2.0.48 */
/* license for this code follows: */

/* */
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * Portions of this software are based upon public domain software
 * originally written at the National Center for Supercomputing Applications,
 * University of Illinois, Urbana-Champaign.
 */

static char *
substring_conf(apr_pool_t *p, const char *start, int len, char quote)
{
    char *result = apr_palloc(p, len + 2);
    char *resp = result;
    int i;

    for (i = 0; i < len; ++i) {
        if (start[i] == '\\' && (start[i + 1] == '\\'
                                 || (quote && start[i + 1] == quote)))
            *resp++ = start[++i];
        else
            *resp++ = start[i];
    }

    *resp++ = '\0';
    return result;
}

char * 
ath_ap_getword_conf(apr_pool_t *p, const char **line)
{
    const char *str = *line, *strend;
    char *res;
    char quote;

    while (*str && apr_isspace(*str))
        ++str;

    if (!*str) {
        *line = str;
        return "";
    }

    if ((quote = *str) == '"' || quote == '\'') {
        strend = str + 1;
        while (*strend && *strend != quote) {
            if (*strend == '\\' && strend[1] && strend[1] == quote)
                strend += 2;
            else
                ++strend;
        }
        res = substring_conf(p, str + 1, strend - str - 1, quote);

        if (*strend == quote)
            ++strend;
    }
    else {
        strend = str;
        while (*strend && !apr_isspace(*strend))
            ++strend;

        res = substring_conf(p, str, strend - str, 0);

   }

    while (*strend && apr_isspace(*strend))
        ++strend;
    *line = strend;
    return res;
}
